001 /* 002 * Copyright 2005 Stephen J. McConnell 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.library.impl; 020 021 import java.util.ArrayList; 022 import java.util.Enumeration; 023 import java.util.Properties; 024 025 import net.dpml.library.Dictionary; 026 import net.dpml.library.info.AbstractDirective; 027 028 import net.dpml.util.PropertyResolver; 029 030 /** 031 * Utility class used for construction of a module model from an XML source. 032 * 033 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 034 * @version 1.1.0 035 */ 036 public class DefaultDictionary implements Dictionary 037 { 038 private final DefaultDictionary m_parent; 039 private final AbstractDirective m_directive; 040 private final Properties m_properties; 041 042 /** 043 * Creation of a new dictionary. The dictionary provides support 044 * for property inheritance within the hierachy of of modules based 045 * an a single root virtual module. When handling a propety request 046 * the dictionary will attempt to resolve the property value using 047 * local property values. If the value is unresolved, the implemenetation 048 * will attempt to delegate the request to a parent dictionary if available. 049 * 050 * @param parent the parent dictionary (possibly null) 051 * @param directive an abstract directive containing local properties 052 */ 053 public DefaultDictionary( DefaultDictionary parent, AbstractDirective directive ) 054 { 055 if( null == directive ) 056 { 057 throw new NullPointerException( "directive" ); 058 } 059 m_parent = parent; 060 m_directive = directive; 061 062 Properties properties = getParentProperties(); 063 m_properties = new Properties( properties ); 064 Properties local = directive.getProperties(); 065 String[] keys = getLocalPropertyNames( local ); 066 for( int i=0; i<keys.length; i++ ) 067 { 068 String key = keys[i]; 069 String value = local.getProperty( key ); 070 m_properties.setProperty( key, value ); 071 } 072 } 073 074 //---------------------------------------------------------------------------- 075 // Dictionary 076 //---------------------------------------------------------------------------- 077 078 /** 079 * Return the property names associated with the dictionary. 080 * @return the array of property names 081 */ 082 public String[] getPropertyNames() 083 { 084 return getLocalPropertyNames( m_properties ); 085 } 086 087 /** 088 * Return the local property names associated with the dictionary. 089 * @return the array of local property names 090 */ 091 public String[] getLocalPropertyNames() 092 { 093 return getLocalPropertyNames( m_directive.getProperties() ); 094 } 095 096 /** 097 * Return a property value. 098 * @param key the property key 099 * @return the property value 100 */ 101 public String getProperty( String key ) 102 { 103 return getProperty( key, null ); 104 } 105 106 /** 107 * Return a property value. 108 * @param key the property key 109 * @param value the default value 110 * @return the property value 111 */ 112 public String getProperty( String key, String value ) 113 { 114 String result = m_properties.getProperty( key, value ); 115 return resolve( result ); 116 } 117 118 /** 119 * Return an integer property value. 120 * @param key the property key 121 * @param value the default value 122 * @return the property value as an integer 123 */ 124 public int getIntegerProperty( String key, int value ) 125 { 126 String result = m_properties.getProperty( key ); 127 if( null == result ) 128 { 129 return value; 130 } 131 else 132 { 133 String literal = resolve( result ); 134 return Integer.parseInt( literal ); 135 } 136 } 137 138 /** 139 * Return an boolean property value. 140 * @param key the property key 141 * @param value the default value 142 * @return the property value as an boolean 143 */ 144 public boolean getBooleanProperty( String key, boolean value ) 145 { 146 String result = m_properties.getProperty( key ); 147 if( null != result ) 148 { 149 return Boolean.valueOf( result ).booleanValue(); 150 } 151 else 152 { 153 return value; 154 } 155 } 156 /** 157 * Evaluate and expand any symbolic references in the supplied value. 158 * @param value the value to resolve 159 * @return the resolved value 160 */ 161 public String resolve( String value ) 162 { 163 return PropertyResolver.resolve( m_properties, value ); 164 } 165 166 //---------------------------------------------------------------------------- 167 // internal 168 //---------------------------------------------------------------------------- 169 170 void setProperty( String name, String value ) 171 { 172 m_properties.setProperty( name, value ); 173 } 174 175 AbstractDirective getAbstractDirective() 176 { 177 return m_directive; 178 } 179 180 Properties getProperties() 181 { 182 return m_properties; 183 } 184 185 private Properties getParentProperties() 186 { 187 if( null == m_parent ) 188 { 189 return new Properties(); 190 } 191 else 192 { 193 return m_parent.getProperties(); 194 } 195 } 196 197 private String[] getLocalPropertyNames( Properties properties ) 198 { 199 ArrayList list = new ArrayList(); 200 Enumeration names = properties.propertyNames(); 201 while( names.hasMoreElements() ) 202 { 203 list.add( (String) names.nextElement() ); 204 } 205 return (String[]) list.toArray( new String[0] ); 206 } 207 208 Properties getExportProperties() 209 { 210 String[] keys = getLocalPropertyNames(); 211 Properties properties = new Properties(); 212 for( int i=0; i<keys.length; i++ ) 213 { 214 String key = keys[i]; 215 String value = getProperty( key ); 216 properties.setProperty( key, value ); 217 } 218 return properties; 219 } 220 }